// /////////////////////////////////////////////////////////////////////////////
//
// Name:            HasEvents.h
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Declaration of the HasEvents class.
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

#ifndef __HASEVENTS_H__
#define __HASEVENTS_H__

// Include files
#include "../dependencies.h"
#include "EventManager.h"


// HasEvents class
//! This class provides a base for classes that need a decentralized event system.
//! By deriving from this class, the derived class gains all needed methods for
//! the management of a decentralized event system.
class HasEvents
{
public:

    // Initialisation and deinitialisation
    //! Constructor
    HasEvents();
    //! Deconstructor
    virtual ~HasEvents();

    // Public methods
    //! Creates a new event slot.
    //! @param slotName      Name of the event slot.
    //! @return True if creation was successful, false if creation was a failure.
    bool createEventSlot(const std::string &slotName);

    //! Connects a function to the given event slot.
    //! @param slotName      Name of the event slot.
    //! @param t             Pointer to the object that will function as this-object when the
    //!                      connect function is called.
    //! @param m             Pointer to the function.
    template<typename T>
    bool connectEventSignal(const std::string &slotName, T *t, void (T::*m)(void*))
    {
        // Get the given event slot.
        std::map<std::string, EventSlot>::iterator itSlots = mEventSlots.find(slotName);

        if(itSlots == mEventSlots.end())
         return false;

        EventSlot &signal = itSlots->second;

        // Connect to the signal.
        signal.connect(t, m);
        return true;
    };

    //! Disconnects a function from the given event slot.
    //! @param slotName      Name of the event slot.
    //! @param t             Pointer to the object that will function as this-object when the
    //!                      connect function is called.
    template<typename T>
    bool disconnectEventSignal(const std::string &slotName, T *t)
    {
        // Get the given event slot.
        std::map<std::string, EventSlot>::iterator itSlots = mEventSlots.find(slotName);

        if(itSlots == mEventSlots.end())
         return false;

        EventSlot &signal = itSlots->second;

        // Disconnect from the signal.
        signal.disconnect(t);
        return true;
    };

    //! Emits an event to the given event slot.
    //! @param slotName      Name of the event slot.
    //! @param p             Pointer to data which will be passed to all functions called.
    bool emitEvent(const std::string &slotName, void* p = 0);

    //! Removes all event slots.
    void removeEventSlots();
    //! Removes the given event slot.
    //! @param slotName      Name of the event slot to remove.
    //! @return True if removal was successful, false if removal was a failure.
    bool removeEventSlot(const std::string &slotName);

private:

    // Private members
    std::map<std::string, EventSlot> mEventSlots;
};

#endif
